package com.csproj.siiat.web.rest.errors;

import com.csproj.siiat.base.common.dto.BaseDTO;
import com.csproj.siiat.base.common.exception.BaseAppException;
import org.springframework.dao.ConcurrencyFailureException;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;

import java.util.List;

/**
 * Controller advice to translate the server side exceptions to client-friendly json structures.
 */
@ControllerAdvice
public class ExceptionTranslator {

    @ExceptionHandler(ConcurrencyFailureException.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ResponseBody
    public BaseDTO processConcurencyError(ConcurrencyFailureException ex) {
        //BaseDTO baseDto = new BaseDTO(HttpStatus.INTERNAL_SERVER_ERROR.value(),"并发故障异常",null);

        BaseDTO baseDTO2 = new BaseDTO(false, true, null, "", "并发故障异常",ex.getMessage());
        return baseDTO2;
    }

    @ExceptionHandler(MethodArgumentTypeMismatchException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ResponseBody
    public BaseDTO processValidationError(MethodArgumentTypeMismatchException ex) {
        //BaseDTO baseDto = new BaseDTO(BaseDTO.CODE_PARAM,"方法参数类型不匹配",null);

        BaseDTO baseDTO2 = new BaseDTO(false, true, null, "", "方法参数类型不匹配",ex.getMessage());
        return baseDTO2;
    }

    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ResponseBody
    public BaseDTO processValidationError(MethodArgumentNotValidException ex) {
        BindingResult result = ex.getBindingResult();
        List<FieldError> fieldErrors = result.getFieldErrors();
        StringBuffer message = new StringBuffer("");
        for (FieldError fieldError : fieldErrors) {
            //message.append("_objectName:"+fieldError.getObjectName()).append("_field:"+fieldError.getField()).append("_code:"+fieldError.getCode());
            message.append(fieldError.getDefaultMessage());
        }
        //BaseDTO baseDto = new BaseDTO(HttpStatus.BAD_REQUEST.value(),message.toString(),null);

        BaseDTO baseDTO2 = new BaseDTO(false, true, null, "", "方法参数类型不匹配", ex.getMessage());
        return baseDTO2;
    }

    @ExceptionHandler(CustomParameterizedException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ResponseBody
    public ParameterizedErrorVM processParameterizedValidationError(CustomParameterizedException ex) {
        return ex.getErrorVM();
    }

    @ExceptionHandler(AccessDeniedException.class)
    @ResponseStatus(HttpStatus.FORBIDDEN)
    @ResponseBody
    public BaseDTO processAccessDeniedException(AccessDeniedException e) {
        //BaseDTO baseDto = new BaseDTO(403,"权限不符，拒绝访问",null);

        BaseDTO baseDTO2 = new BaseDTO(false, false, null, "", "403", "权限不符，拒绝访问");
        return baseDTO2;
    }

    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    @ResponseBody
    @ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
    public BaseDTO processMethodNotSupportedException(HttpRequestMethodNotSupportedException exception) {
        //BaseDTO baseDto = new BaseDTO(HttpStatus.METHOD_NOT_ALLOWED.value(), ErrorConstants.ERR_METHOD_NOT_SUPPORTED,null);

        BaseDTO baseDTO2 = new BaseDTO(false, true, null, "", ErrorConstants.ERR_METHOD_NOT_SUPPORTED, exception.getMessage());
        return baseDTO2;
    }

    @ExceptionHandler(BaseAppException.class)
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public BaseDTO baseAppException(BaseAppException be) {
        BaseDTO baseDTO2 = new BaseDTO(be.getSuccess(), true, null, "", be.getMessage(), be.getMessage());

        return baseDTO2;
    }

    @ExceptionHandler(InsufficientAuthenticationException.class)
    @ResponseStatus(HttpStatus.FORBIDDEN)
    @ResponseBody
    public BaseDTO InsufficientAuthenticationException(Exception be) {
        //BaseDTO.createBaseDTO().setCode(403).setMessage("请确认登录，请联系管理员！");
        BaseDTO baseDTO2 = new BaseDTO(false, false, null, "", "401", "请确认登录，请联系管理员！");

        return baseDTO2;
    }

    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ResponseBody
    public BaseDTO exception(Exception be) {
        be.printStackTrace();
        //BaseDTO.createBaseDTO().setCode(500).setMessage("系统繁忙，请联系管理员！");

        BaseDTO baseDTO2 = new BaseDTO(false, true, null, "", "500", be.getMessage());
        return baseDTO2;
    }
}
